package calculateArea;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class CalculateArea {
    private JFrame mainFrame;
    private Font font = new Font("黑体", Font.PLAIN, 20);
    
    abstract static class MyShape {
        protected double area;
        protected double perimeter;
        
        public double getArea() {
            return area;
        }
        
        public double getPerimeter() {
            return perimeter;
        }
        
        public abstract double calculateArea();
        public abstract double calculatePerimeter();
    }
    
    // 长方形
    static class Rectangle extends MyShape {
        private double length;
        private double width;
        
        public void setLength(double length) {
            this.length = length;
        }
        
        public void setWidth(double width) {
            this.width = width;
        }
        
        @Override
        public double calculateArea() {
            area = length * width;
            BigDecimal bd = new BigDecimal(area);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
        
        @Override
        public double calculatePerimeter() {
            perimeter = 2 * (length + width);
            BigDecimal bd = new BigDecimal(perimeter);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
    }
    
    
    // 正方形
    static class Square extends MyShape {
        private double length;
        
        public void setLength(double length) {
            this.length = length;
        }
        
        @Override
        public double calculateArea() {
            area = length * length;
            BigDecimal bd = new BigDecimal(area);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
        
        @Override
        public double calculatePerimeter() {
            perimeter = length * 4;
            BigDecimal bd = new BigDecimal(perimeter);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
    }
    
    // 等腰三角形
    static class IsoscelesTriangle extends MyShape {
        private double base;
        private double height;
        
        public void setBase(double base) {
            this.base = base;
        }
        
        public void setHeight(double height) {
            this.height = height;
        }
        
        @Override
        public double calculateArea() {
            area = base * height / 2;
            BigDecimal bd = new BigDecimal(area);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
        
        @Override
        public double calculatePerimeter() {
            double side = Math.sqrt(Math.pow(base / 2, 2) + Math.pow(height, 2));
            perimeter = side * 2 + base;
            BigDecimal bd = new BigDecimal(perimeter);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
    }
    
    // 等腰梯形
    static class IsoscelesTrapezoid extends MyShape {
        private double height;
        private double upperLine;
        private double lowerLine;
        
        public void setHeight(double height) {
            this.height = height;
        }
        
        public void setUpperLine(double upperLine) {
            this.upperLine = upperLine;
        }
        
        public void setLowerLine(double lowerLine) {
            this.lowerLine = lowerLine;
        }
        
        @Override
        public double calculateArea() {
            area = (upperLine + lowerLine) * height / 2;
            BigDecimal bd = new BigDecimal(area);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
        
        @Override
        public double calculatePerimeter() {
            double side = Math.sqrt(Math.pow((lowerLine - upperLine) / 2, 2) + Math.pow(height, 2));
            perimeter = upperLine + lowerLine + 2 * side;
            BigDecimal bd = new BigDecimal(perimeter);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
    }
    
    // 平行四边形
    static class Parallelogram extends MyShape {
        private double base;
        private double side;
        private double height;
        
        public void setBase(double base) {
            this.base = base;
        }
        
        public void setSide(double side) {
            this.side = side;
        }
        
        public void setHeight(double height) {
            this.height = height;
        }
        
        @Override
        public double calculateArea() {
            area = base * height;
            BigDecimal bd = new BigDecimal(area);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
        
        @Override
        public double calculatePerimeter() {
            perimeter = 2 * (base + side);
            BigDecimal bd = new BigDecimal(perimeter);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
    }
    
    // 圆形
    static class Circle extends MyShape {
        private static final double PI = 3.141592653589793;
        private double radius;
        
        public void setRadius(double radius) {
            this.radius = radius;
        }
        
        @Override
        public double calculateArea() {
            area = PI * radius * radius;
            BigDecimal bd = new BigDecimal(area);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
        
        @Override
        public double calculatePerimeter() {
            perimeter = 2 * PI * radius;
            BigDecimal bd = new BigDecimal(perimeter);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            return bd.doubleValue();
        }
    }
    
    // 计算器界面
    class Calculator {
        private JFrame calculatorFrame;
        private JPanel inputPanel;
        private JPanel resultPanel;
        private JButton calculateButton;
        private JButton backButton;
        private String selectedShape;
        private JTextField[] textFields; 
        
        /**
         * 初始化计算器界面
         * shape 选择的图形类型
         */
        public void calculatorInit(String shape) {
            this.selectedShape = shape;
            
            calculatorFrame = new JFrame(shape + "的面积与周长计算");
            calculatorFrame.setLayout(new BorderLayout(10, 10));
            calculatorFrame.setSize(400, 300);
            
            // 输入面板
            inputPanel = new JPanel();
            inputPanel.setLayout(new GridLayout(0, 2, 10, 10));
            
            // 根据图形类型添加不同的输入字段
            switch (shape) {
                case "长方形":
                    inputPanel.add(new JLabel("长度:"));
                    JTextField lengthField = new JTextField();
                    inputPanel.add(lengthField);
                    
                    inputPanel.add(new JLabel("宽度:"));
                    JTextField widthField = new JTextField();
                    inputPanel.add(widthField);
                    
                    textFields = new JTextField[]{lengthField, widthField};
                    break;
                    
                case "正方形":
                    inputPanel.add(new JLabel("边长:"));
                    JTextField sideField = new JTextField();
                    inputPanel.add(sideField);
                    
                    textFields = new JTextField[]{sideField};
                    break;
                    
                case "等腰三角形":
                    inputPanel.add(new JLabel("底边:"));
                    JTextField baseField = new JTextField();
                    inputPanel.add(baseField);
                    
                    inputPanel.add(new JLabel("高度:"));
                    JTextField heightField = new JTextField();
                    inputPanel.add(heightField);
                    
                    textFields = new JTextField[]{baseField, heightField};
                    break;
                    
                case "等腰梯形":
                    inputPanel.add(new JLabel("上底:"));
                    JTextField upperLineField = new JTextField();
                    inputPanel.add(upperLineField);
                    
                    inputPanel.add(new JLabel("下底:"));
                    JTextField lowerLineField = new JTextField();
                    inputPanel.add(lowerLineField);
                    
                    inputPanel.add(new JLabel("高度:"));
                    JTextField trapezoidHeightField = new JTextField();
                    inputPanel.add(trapezoidHeightField);
                    
                    textFields = new JTextField[]{upperLineField, lowerLineField, trapezoidHeightField};
                    break;
                    
                case "平行四边形":
                    inputPanel.add(new JLabel("底边:"));
                    JTextField parallelogramBaseField = new JTextField();
                    inputPanel.add(parallelogramBaseField);
                    
                    inputPanel.add(new JLabel("侧边:"));
                    JTextField parallelogramSideField = new JTextField();
                    inputPanel.add(parallelogramSideField);
                    
                    inputPanel.add(new JLabel("高度:"));
                    JTextField parallelogramHeightField = new JTextField();
                    inputPanel.add(parallelogramHeightField);
                    
                    textFields = new JTextField[]{parallelogramBaseField, parallelogramSideField, parallelogramHeightField};
                    break;
                    
                case "圆形":
                    inputPanel.add(new JLabel("半径:"));
                    JTextField radiusField = new JTextField();
                    inputPanel.add(radiusField);
                    
                    textFields = new JTextField[]{radiusField};
                    break;
                    
                default:
                    textFields = new JTextField[0];
                    break;
            }
            
            // 按钮面板
            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(new FlowLayout());
            
            // 计算按钮
            calculateButton = new JButton("计算");
            buttonPanel.add(calculateButton);
            
            // 返回按钮
            backButton = new JButton("返回");
            buttonPanel.add(backButton);
            
            // 结果面板
            resultPanel = new JPanel();
            resultPanel.setLayout(new GridLayout(2, 2, 10, 10));
            resultPanel.add(new JLabel("面积: "));
            JLabel areaLabel = new JLabel("0.0");
            resultPanel.add(areaLabel);
            
            resultPanel.add(new JLabel("周长: "));
            JLabel perimeterLabel = new JLabel("0.0");
            resultPanel.add(perimeterLabel);
            
            // 主面板
            JPanel mainPanel = new JPanel();
            mainPanel.setLayout(new BorderLayout(10, 10));
            mainPanel.add(inputPanel, BorderLayout.NORTH);
            mainPanel.add(resultPanel, BorderLayout.CENTER);
            mainPanel.add(buttonPanel, BorderLayout.SOUTH);
            
            calculatorFrame.add(mainPanel);
            
            toCenter(calculatorFrame);
            calculatorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            calculatorFrame.setVisible(true);
            calculatorFrame.setResizable(false);
            
            // 添加计算按钮事件
            calculateButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        MyShape shape = null;
                        
                        switch (selectedShape) {
                            case "长方形":
                                Rectangle rectangle = new Rectangle();
                                rectangle.setLength(Double.parseDouble(textFields[0].getText()));
                                rectangle.setWidth(Double.parseDouble(textFields[1].getText()));
                                shape = rectangle;
                                break;
                                
                            case "正方形":
                                Square square = new Square();
                                square.setLength(Double.parseDouble(textFields[0].getText()));
                                shape = square;
                                break;
                                
                            case "等腰三角形":
                                IsoscelesTriangle triangle = new IsoscelesTriangle();
                                triangle.setBase(Double.parseDouble(textFields[0].getText()));
                                triangle.setHeight(Double.parseDouble(textFields[1].getText()));
                                shape = triangle;
                                break;
                                
                            case "等腰梯形":
                                IsoscelesTrapezoid trapezoid = new IsoscelesTrapezoid();
                                trapezoid.setUpperLine(Double.parseDouble(textFields[0].getText()));
                                trapezoid.setLowerLine(Double.parseDouble(textFields[1].getText()));
                                trapezoid.setHeight(Double.parseDouble(textFields[2].getText()));
                                shape = trapezoid;
                                break;
                                
                            case "平行四边形":
                                Parallelogram parallelogram = new Parallelogram();
                                parallelogram.setBase(Double.parseDouble(textFields[0].getText()));
                                parallelogram.setSide(Double.parseDouble(textFields[1].getText()));
                                parallelogram.setHeight(Double.parseDouble(textFields[2].getText()));
                                shape = parallelogram;
                                break;
                                
                            case "圆形":
                                Circle circle = new Circle();
                                circle.setRadius(Double.parseDouble(textFields[0].getText()));
                                shape = circle;
                                break;
                                
                            default:
                                break;
                        }
                        
                        if (shape != null) {
                            double area = shape.calculateArea();
                            double perimeter = shape.calculatePerimeter();
                            
                            areaLabel.setText(String.format("%.2f", area));
                            perimeterLabel.setText(String.format("%.2f", perimeter));
                        }
                    } catch (NumberFormatException ex) {
                        JOptionPane.showMessageDialog(calculatorFrame, 
                                "请输入有效的数字!", "错误", JOptionPane.ERROR_MESSAGE);
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(calculatorFrame, 
                                "计算错误: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            
            // 添加返回按钮事件
            backButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    calculatorFrame.dispose();
                    mainFrame.setVisible(true);
                }
            });
        }
    }
    
    // 初始化主界面
    public void uiInit() {
        String[] figures = {"长方形", "正方形", "等腰三角形", "等腰梯形", "平行四边形", "圆形"};
        mainFrame = new JFrame("图形的面积与周长计算");
        mainFrame.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 20));
        mainFrame.setSize(400, 200);
        
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout(10, 10));
        
        JLabel label = new JLabel("请选择图形");
        label.setFont(font);
        label.setHorizontalAlignment(JLabel.CENTER);
        panel.add(label, BorderLayout.NORTH);
        
        JComboBox<String> comboBox = new JComboBox<>(figures);
        comboBox.setFont(font);
        panel.add(comboBox, BorderLayout.CENTER);
        
        JButton confirmButton = new JButton("确认");
        confirmButton.setFont(font);
        panel.add(confirmButton, BorderLayout.SOUTH);
        
        mainFrame.add(panel);
        
        toCenter(mainFrame);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setVisible(true);
        mainFrame.setResizable(false);
        
        confirmButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String selectedShape = (String) comboBox.getSelectedItem();
                mainFrame.setVisible(false);
                Calculator calculator = new Calculator();
                calculator.calculatorInit(selectedShape);
            }
        });
    }
    
    /**
     * 将组件居中显示
     * component 要居中的组件
     */
    public static void toCenter(Component component) {
        GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        java.awt.Rectangle rectangle = graphicsEnvironment.getDefaultScreenDevice()
                .getDefaultConfiguration().getBounds();
        component.setLocation(
            ((int) rectangle.getWidth() - component.getWidth()) / 2,
            ((int) rectangle.getHeight() - component.getHeight()) / 2
        );
    }
    
    /**
     * 主方法
     * args 命令行参数
     */
    public static void main(String[] args) {
        CalculateArea figureCalculator = new CalculateArea();
        figureCalculator.uiInit();
    }
}